package main

import (
	"context"
	"fmt"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"log"
	"net/http"
	authpb "serve/auth/api/gen/v1"
	carpb "serve/car/api/gen/v1"
	rentalpb "serve/rental/api/gen/v1"
	"serve/settings"
	"serve/shared/server"
)

// 主要用于http服务和grpc服务的对应
// 启动这个服务后，就可以像调用http那样调用grpc
// 当然需要生成grpc的时候，生成geteway
func main() {

	logger, err := server.NewZapLogger()
	if err != nil {
		log.Fatalf("cannot create logger err %v", err)
	}

	c := context.Background()          // 创建一个context
	c, cancel := context.WithCancel(c) // 返回一个context的副本，并返回了一个cancel
	defer cancel()                     //调用cancel中断任务

	mux := runtime.NewServeMux(runtime.WithMarshalerOption( // 看不懂
		runtime.MIMEWildcard, &runtime.JSONPb{
			EnumsAsInts: true, // 转换枚举
			OrigName:    true, // 原始名称
		}))

	err = settings.Init()
	if err != nil {
		logger.Fatal(" settings.Init() %v", zap.Error(err))
	}

	serverConfig := []struct {
		name         string
		addr         string
		registerFunc func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error)
	}{
		{
			name:         "auth",
			addr:         fmt.Sprintf("%s:%d", viper.GetString("auth.srv.host"), viper.GetInt("auth.srv.port")),
			registerFunc: authpb.RegisterAuthServiceHandlerFromEndpoint,
		},
		{
			name:         "trip",
			addr:         fmt.Sprintf("%s:%d", viper.GetString("rental.srv.host"), viper.GetInt("rental.srv.port")),
			registerFunc: rentalpb.RegisterTripServiceHandlerFromEndpoint,
		},
		{
			name:         "profile",
			addr:         fmt.Sprintf("%s:%d", viper.GetString("rental.srv.host"), viper.GetInt("rental.srv.port")),
			registerFunc: rentalpb.RegisterProfileServiceHandlerFromEndpoint,
		},
		{
			name:         "car",
			addr:         fmt.Sprintf("%s:%d", viper.GetString("car.srv.host"), viper.GetInt("car.srv.port")),
			registerFunc: carpb.RegisterCarServiceHandlerFromEndpoint,
		},
	}

	for _, s := range serverConfig {
		err = s.registerFunc( // 注册这个服务
			c, mux, s.addr,
			[]grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())})

		if err != nil {
			logger.Fatal("cannot register %s service: %v", zap.String("name", s.name), zap.Error(err))
		}
	}
	port := viper.GetInt("auth.web.port")
	logger.Sugar().Infof("grpc gateway satrted at %d", port)
	logger.Sugar().Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), mux)) // 启动服务
}
